Skip to content

feat: build kit xcframeworks from SPM packages instead of Xcode projects#729

Open
thomson-t wants to merge 2 commits intomainfrom
feat/spm-kit-xcframework
Open

feat: build kit xcframeworks from SPM packages instead of Xcode projects#729
thomson-t wants to merge 2 commits intomainfrom
feat/spm-kit-xcframework

Conversation

@thomson-t
Copy link
Copy Markdown
Contributor

@thomson-t thomson-t commented Apr 8, 2026

Summary

  • Remove all 29 kit-level .xcodeproj directories and 5 tvOS-specific header directories (mParticle-*-tvOS/), replacing the xcodeproj-based xcframework build with Scripts/build_kit_xcframework.sh that archives directly from each kit's Package.swift using xcodebuild -skipPackagePluginValidation
  • Simplify Kits/matrix.json from separate per-platform schemes to a single scheme + module + platforms[] per kit
  • Update release-publish.yml and build-kits.yml workflows to use the new SPM-based build approach

Motivation

Kit .xcodeproj files were only used to generate xcframeworks during release. Every kit already has a Package.swift that defines the same targets and dependencies. By building directly from SPM, we:

  • Eliminate ~16,000 lines of generated Xcode project files
  • Remove the need to maintain separate tvOS Xcode schemes (SPM handles multi-platform with a single scheme)
  • Align the xcframework build with how consumers actually integrate kits (via SPM)

Key changes

New: Scripts/build_kit_xcframework.sh

Reusable script that builds an xcframework from an SPM package for one or more platforms. Handles:

  • xcodebuild archive with -skipPackagePluginValidation (no .xcodeproj needed)
  • Post-processing to copy public headers and generate module.modulemap into framework bundles
  • Multi-platform builds (iOS + tvOS) from a single SPM scheme
  • Sets BUILD_XCFRAMEWORK=1 to signal Package.swift to use dynamic library type

Updated: Kits/matrix.json

Simplified from:

"schemes": [
  {"scheme": "mParticle-Braze", "module": "mParticle_Braze", "destination": "iOS"},
  {"scheme": "mParticle-Braze-tvOS", "module": "mParticle_Braze", "destination": "tvOS"}
]

To:

"scheme": "mParticle-Braze",
"module": "mParticle_Braze",
"platforms": ["iOS", "tvOS"]

Updated: 29 kit Package.swift files

  • Added BUILD_XCFRAMEWORK env var to conditionally set .dynamic library type (required for framework output from SPM)
  • Added explicit name: "mparticle-apple-sdk" on local path dependency for SPM identity resolution
  • No changes to remote dependency resolution or public API

Deleted

  • 29 kit .xcodeproj directories (project files + shared schemes)
  • 5 mParticle-*-tvOS/ directories from Braze (3) and Kochava (2) kits — only contained tvOS headers/plists used by the Xcode project's tvOS target

Test plan

  • Verify Scripts/build_kit_xcframework.sh produces valid xcframeworks for an iOS-only kit (e.g., Adjust) and a multi-platform kit (e.g., Braze)
  • Trigger Release – Publish workflow with dry_run: true to validate the full CI pipeline
  • Verify Build Kits CI workflow passes for all 29 kits
  • Confirm xcframework zip contents include headers, module maps, and dSYMs
  • Verify SPM consumers can still resolve kit packages (no public API change)

@thomson-t thomson-t requested a review from a team as a code owner April 8, 2026 20:14
@cursor
Copy link
Copy Markdown

cursor bot commented Apr 8, 2026

PR Summary

Medium Risk
Changes the kit build and release pipeline to archive via SPM and a new script, which could impact release artifacts and multi-platform slices if scheme/platform metadata is wrong. No runtime SDK logic changes, but CI/release failures would block publishing.

Overview
Kit xcframework generation is moved from per-kit .xcodeproj builds to SPM-based archives. release-publish.yml now selects Xcode per kit (optional xcode_version) and calls the new Scripts/build_kit_xcframework.sh with a simplified Kits/matrix.json (scheme + module + platforms[]).

build-kits.yml is updated to resolve/build/test using the single kit scheme across all configured platforms, with -skipPackagePluginValidation and consistent working-directory usage.

Across kit Package.swift files, local SDK dependencies are given an explicit package name and libraries conditionally switch to .dynamic when BUILD_XCFRAMEWORK=1; numerous kit .xcodeproj/scheme files and tvOS-specific header/plist folders are removed, and a new KIT_XCFRAMEWORK_RELEASE_WORKFLOW.md documents the new flow.

Reviewed by Cursor Bugbot for commit 84d4990. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 8, 2026

📦 SDK Size Impact Report

Measures how much the SDK adds to an app's size (with-SDK minus without-SDK).

Metric Target Branch This PR Change
App Bundle Impact 1.75 MB 1.75 MB +N/A
Executable Impact 848 bytes 848 bytes +N/A
XCFramework Size 6.38 MB 6.38 MB +N/A

➡️ SDK size impact change is minimal.

Raw measurements

Target branch (main):

{"baseline_app_size_kb":84,"baseline_executable_size_bytes":75464,"with_sdk_app_size_kb":1876,"with_sdk_executable_size_bytes":76312,"sdk_impact_kb":1792,"sdk_executable_impact_bytes":848,"xcframework_size_kb":6528}

This PR:

{"baseline_app_size_kb":84,"baseline_executable_size_bytes":75464,"with_sdk_app_size_kb":1876,"with_sdk_executable_size_bytes":76312,"sdk_impact_kb":1792,"sdk_executable_impact_bytes":848,"xcframework_size_kb":6528}

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a2f4b2a. Configure here.

HEADERS_DIR="Sources/${SCHEME}/include"

XCFRAMEWORK_ARGS=""
FRAMEWORK_NAME="${SCHEME}.framework"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong framework name: uses SCHEME instead of MODULE

High Severity

FRAMEWORK_NAME is set to "${SCHEME}.framework" (e.g., mParticle-Braze.framework) but xcodebuild archive from an SPM package produces framework bundles using the c99 extended identifier form with underscores (e.g., mParticle_Braze.framework). The existing Scripts/xcframework.sh and the deleted old workflow code both correctly use $MODULE.framework for the -framework argument. This mismatch causes the header/modulemap post-processing to silently skip (the -d check fails) and xcodebuild -create-xcframework to fail because it can't find the framework. Affects all 29 kits.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a2f4b2a. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module name inside the framework uses underscores (mParticle_Adjust), but the bundle name uses hyphens

Remove kit-level .xcodeproj files and tvOS-specific directories, replacing
the xcodeproj-based xcframework build with a script that archives directly
from each kit's Package.swift using xcodebuild -skipPackagePluginValidation.

- Add Scripts/build_kit_xcframework.sh for SPM-based xcframework generation
- Simplify Kits/matrix.json to scheme + module + platforms[] per kit
- Update release-publish.yml and build-kits.yml to use the new format
- Update all 29 kit Package.swift files with BUILD_XCFRAMEWORK dynamic type
  and explicit package identity for local path dependencies
- Delete 29 kit .xcodeproj directories and 5 tvOS header directories
- Update KIT_XCFRAMEWORK_RELEASE_WORKFLOW.md to document the new approach
@thomson-t thomson-t force-pushed the feat/spm-kit-xcframework branch from a2f4b2a to e83842e Compare April 10, 2026 13:31
Xcode 16.4 fails to verify the core SDK's swiftinterface due to the
multi-module ObjC/Swift structure introduced in v9.0.0. Remove the
xcode_version override so Braze kits build with the default Xcode
version like all other kits.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant